#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <cassert>
#include <sys/types.h>
#include <sys/wait.h>

// using namespace std;
using std::cout;
using std::endl;

// 使用sigchld，信号回收子进程,两种方法：1：用，2.不用chld，直接捕获为忽略
void child_handler(int signal)
{
    // 判断是否是17号信号
    assert(signal == 17);

    while (true) // 若不是循环判断，若多个子进程同时退出，那就无法等待到
    {
        pid_t n = waitpid(-1, nullptr, WNOHANG); // 非阻塞等待。一直循环问
        if (n > 0)
        {
            cout << "进程等待成功，pid为: " << getpid() << "的子进程退出" << endl;
        }
        else if (n == 0)
        {
            break;
        }
        else
        {
            cout << "所有进程全部退出" << endl;
            break;
        }
    }
}

int main()
{
    // 捕捉17，sigchld信号
    struct sigaction act, oldact;
    act.sa_handler = child_handler;
    // act.__sigaction_handler//不是这个
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, 2);
    sigaction(17, &act, &oldact);
    // signal(17,child_handler);

    for (int i = 0; i < 10; i++)
    {
        sleep(1);
        pid_t id = fork();
        if (id == 0)
        {
            // 子进程
            int cnt = 10;
            while (cnt--)
            {
                cout << "我是子进程: " << i << "，我的pid是: " << getpid() << " ,还剩" << cnt << "秒退出" << endl;
                sleep(1);
            }
            exit(0);
        }
    } // 父进程创建完毕子进程后，就会自己执行剩下的工作。
    while (true)
    {
        cout << "我是符进程，我的pid是: " << getpid() << " 我一直在工作" << endl;
        sleep(2);
    }

    // 等待回收子进程。但是父进程有自己的工作需要做。

    return 0;
}
